<template>
    <div v-loading="loading" class="console-page">
        <el-form inline :model="searchForm" class="e-page form-item" spellcheck="false" @submit.native.prevent>
            <el-row class="toolbar" ref="el">
                <el-col :span="4" style="padding-right: 5px">
                    <el-input v-model="searchForm.name" placeholder="连接名称" clearable class="input-auto-resize" />
                </el-col>
                <el-col :span="4" style="padding-right: 5px">
                    <el-input v-model="searchForm.connectionInfo" placeholder="连接信息" clearable
                        class="input-auto-resize" />
                </el-col>
                <el-col :span="4" style="padding-right: 5px">
                    <el-select v-model="searchForm.status" clearable placeholder="请选择状态" class="input-auto-resize">
                        <el-option v-for="item in statusSelect" :key="item.value" :label="item.label"
                            :value="item.value" />
                    </el-select>
                </el-col>
                <el-col :span="4" style="padding-right: 5px">
                    <el-button type="primary" @click="searchTable" circle :icon="getIcon('search')"
                        :loading="bt_loading" class="button-auto-resize" native-type="submit" />
                </el-col>
                <el-col :span="8" style="text-align: right" v-permission="$permission.Write">
                    <el-dropdown placement="bottom" trigger="click">
                        <span class="el-dropdown-link">
                            <el-button :icon="getIcon('plus')" circle class="input-auto-resize" />
                        </span>
                        <template #dropdown>
                            <el-dropdown-menu style="min-width: 100px;">
                                <el-dropdown-item v-for="(db, index) in dbType" :icon="getIcon('ElementPlus')"
                                    @click.native="openDialog('new', db)" :key="index">
                                    <span>{{ db.name.replace(db.name[0], db.name[0].toUpperCase()) }}</span>
                                </el-dropdown-item>
                            </el-dropdown-menu>
                        </template>
                    </el-dropdown>
                </el-col>
            </el-row>
        </el-form>
        <el-table :data="tableData" border header-cell-class-name="el-table-header-cell" cell-class-name="el-table-cell"
            class="e-page table-with-pagination" highlight-current-row>
            <el-table-column prop="dbType" label="连接类型" :width="fontAutoResize.size_8.value" />
            <el-table-column prop="name" label="连接名称" width="150" />
            <el-table-column prop="connectionInfo" label="连接信息" min-width="200" />
            <el-table-column prop="username" label="用户名" :width="fontAutoResize.size_10.value" />
            <el-table-column prop="status" label="状态" :width="fontAutoResize.size_6.value">
                <template #default="scope">
                    <!-- 状态 -->
                    <el-tag :type="scope.row.status === 1 ? 'primary' : 'danger'" class="button-auto-resize"
                        disable-transitions>{{
                            scope.row.status === 1 ? '正常' : '异常' }}
                    </el-tag>
                </template>
            </el-table-column>
            <el-table-column prop="creator" label="创建人" width="100" />
            <el-table-column prop="crtTime" label="创建时间" :width="fontAutoResize.size_11.value" />
            <el-table-column prop="updateTime" label="更新时间" :width="fontAutoResize.size_11.value" />
            <el-table-column label="操作" :width="operationWidth" className="operation-column"
                v-permission="$permission.Update">
                <template #default="scope">
                    <el-button type="primary" :icon="getIcon('editPen')" circle class="button-auto-resize"
                        @click="openDialog('open', scope.row)" />
                    <el-button type="primary" :icon="getIcon('refresh')" circle class="button-auto-resize"
                        :loading="submit_loading" @click="refreshLink(scope.row)" />
                </template>
            </el-table-column>
        </el-table>
        <div style="height: 50px;">
            <el-pagination background @size-change="SizeChange" @current-change="CurrentChange"
                :current-page="currentPage" :page-sizes="page_sizes" :page-size="page_size"
                layout="total, sizes, prev, pager, next, jumper" prev-text="<上一页" next-text="下一页>" :total="total"
                class="e-page">
            </el-pagination>
        </div>
        <el-dialog title="连接信息" v-model="dialogTableVisible" class="connectStyle" :close-on-click-modal="false"
            @close="close" @submit.native.prevent append-to-body>
            <el-form :model="modifyConnection" status-icon ref="modifyConnectionRef" label-width="100px" class="e-page"
                spellcheck="false">
                <el-form-item label="连接名称" prop="name">
                    <el-input v-model="modifyConnection.name" autocomplete="off" class="input-auto-resize" />
                </el-form-item>
                <el-form-item label="连接信息" prop="connectionInfo">
                    <el-input v-model="modifyConnection.connection_info" autocomplete="off" class="input-auto-resize" />
                </el-form-item>
                <el-form-item label="用户名" prop="username">
                    <el-input v-model="modifyConnection.username" autocomplete="off" class="input-auto-resize" />
                </el-form-item>
                <el-form-item label="密码" prop="password">
                    <el-input v-model="modifyConnection.password" autocomplete="off" type="password"
                        class="input-auto-resize pwd" />
                </el-form-item>
            </el-form>
            <template #footer>
                <span>
                    <el-button @click="confirm" :icon="getIcon('link')" circle class="button-auto-resize"
                        :loading="submit_loading" />
                    <el-button type="primary" :disabled="!commitFlg" @click="submitForm" :loading="submit_loading"
                        :icon="getIcon('check')" circle class="button-auto-resize" />
                </span>
            </template>
        </el-dialog>
    </div>
</template>
<script setup>
import { useElMessage, useSetTableOperationWidth, useModalSize, useRequest } from "@usehook"
import { isInArray, getIcon } from "@/utils/tools"
import { fontAutoResize } from "@/utils/setting"

const operationWidth = useSetTableOperationWidth(2)
let tableData = $ref([])
let currentPage = $ref(1)
let page_size = $ref(0)
let total = $ref(0)
let statusSelect = [{ value: 1, label: '正常' }, { value: 0, label: '异常' }]
let dialogTableVisible = $ref(false)
let modifyConnection = $ref({
    sequence: '',
    name: '',
    connection_info: 'jdbc:<dbType>://<Host>:<Port>/<dbName>?useUnicode=true&characterEncoding=utf8',
    username: '',
    password: '',
    status: '',
    isChanged: false
})
let searchForm = $ref({
    name: '',
    status: '',
    connectionInfo: ''
})
let loading = $ref(false)
let bt_loading = $ref(false)
let commitFlg = $ref(false)
let page_sizes = [10, 30, 50, 100, 200]
let dbType = [{
    name: 'oracle',
    icon: '',
    default: 'jdbc:oracle:thin:@<Host>:<1521>:<dbName>'
}, {
    name: 'mysql',
    icon: '',
    default: 'jdbc:mysql://<Host>:<3306>/<dbName>?useUnicode=true&characterEncoding=utf8'
}, {
    name: 'sqlServer',
    icon: '',
    default: 'jdbc:sqlserver://<Host>:<1433>;DatabaseName=<dbName>'
}, {
    name: 'dm',
    icon: '',
    default: 'jdbc:dm://<Host>:<5236>/<dbName>'
}]
let addType = $ref("")
let submit_loading = $ref(false)

const jdbcType = $computed(() => {
    let db = []
    dbType.forEach((e) => {
        if (e.default.startsWith("jdbc")) {
            db.push(e.name)
        }
    })
    return db
})

const close = () => {
    useModalSize(false)
    clearValidate('modifyConnection')
    submit_loading = false
}

const getConnectionInfo = (params) => {
    loading = true
    bt_loading = true
    useRequest({ url: "/data/connection/getData", ...params }).then(resp => {
        if (resp.status) { //0表示成功，1表示失败
            tableData = resp.data
            total = resp.totalRecord
        } else if (resp.message) useElMessage(resp.message)
    }).finally(_ => {
        loading = false
        bt_loading = false
    })
}

const modifyConnectionInfo = (connection, notify) => {
    submit_loading = true
    useRequest({ method: "post", ...connection }).then(resp => {
        if (resp.status) { //0表示成功，1表示失败
            if (notify) {
                if (resp.message) useElMessage(resp.message)
            }
            if (connection.url.endsWith('modify') || connection.url.endsWith('monitor') || connection.updateStatus) {
                refreshTable()
                dialogTableVisible = false
            } else if (connection.url.endsWith('checkConnect')) {
                commitFlg = true
            }
        } else {
            if (resp.message) useElMessage.error(resp.message)
            commitFlg = false
        }
    }).finally(_ => {
        submit_loading = false
    })
}

const { proxy } = getCurrentInstance()

const clearValidate = (formName) => {
    if (proxy.$refs[formName]) {
        proxy.$refs[formName].clearValidate()
    }
}

const validateConnect = () => {
    if (isInArray(addType, jdbcType)) {
        if (!modifyConnection.connection_info.toLowerCase().startsWith('jdbc:' + addType.toLowerCase())) {
            useElMessage.error('连接信息必须以jdbc:' + addType + '开头')
            return false
        } else if (!modifyConnection.username) {
            useElMessage.error('用户名不能为空')
            return false
        } else if (!modifyConnection.password && !modifyConnection.sequence) {
            useElMessage.error('密码不能为空')
            return false
        }
    } else {
        useElMessage.error('未知的类型:' + addType)
        return false
    }
    if (!modifyConnection.name) {
        useElMessage.error('连接名称不能为空')
        return false
    }
    return true
}

const confirm = () => {
    let cm = validateConnect()
    let connection = { connection: modifyConnection, url: '/data/connection/checkConnect', type: addType }
    if (cm) {
        modifyConnectionInfo(connection, true)
    } else {
        return false
    }
}

const searchTable = () => {
    getConnectionInfo({
        'search': JSON.stringify(searchForm), 'limit': page_size, 'page': 1
    })
    currentPage = 1
}

const refreshTable = () => {
    setTimeout(() => {
        getConnectionInfo({
            'search': JSON.stringify(searchForm), 'limit': page_size, 'page': currentPage
        })
    }, 200)
}

const refreshLink = (row) => {
    let connection = {
        connection: { sequence: row.sequence },
        url: '/data/connection/checkConnect',
        type: addType,
        updateStatus: true
    }
    modifyConnectionInfo(connection, true)
}

const submitForm = () => {
    let cm = validateConnect()

    if (cm) {
        modifyConnectionInfo({
            connection: modifyConnection,
            url: '/data/connection/modify',
            type: addType
        }, true)

    } else {
        return false
    }
}

const setMonitor = (sequence) => {
    modifyConnectionInfo({ sequence: sequence, url: '/data/connection/monitor' }, "monitor")
}

const openDialog = (type, connectionInfo) => {
    useModalSize()
    commitFlg = false
    if (type === 'new') {
        addType = connectionInfo.name
        modifyConnection.name = ''
        modifyConnection.connection_info = connectionInfo.default
        modifyConnection.username = ''
        modifyConnection.password = ''
        modifyConnection.sequence = ''
        modifyConnection.isChanged = false
    } else {
        addType = connectionInfo.dbType
        modifyConnection.name = connectionInfo.name
        modifyConnection.connection_info = connectionInfo.connectionInfo
        modifyConnection.username = connectionInfo.username
        modifyConnection.password = ''
        modifyConnection.sequence = connectionInfo.sequence
        modifyConnection.isChanged = false
    }
    dialogTableVisible = true
}

const SizeChange = (val) => {
    getConnectionInfo({
        'search': JSON.stringify(searchForm), 'limit': val, 'page': currentPage
    })
    page_size = val
}

const CurrentChange = (val) => {
    getConnectionInfo({
        'search': JSON.stringify(searchForm), 'limit': page_size, 'page': val
    })
    currentPage = val
}

onMounted(() => {
    page_size = page_sizes[1]
    getConnectionInfo({
        'search': JSON.stringify(searchForm), 'limit': page_size, 'page': currentPage
    })
})

watch(() => modifyConnection, () => {
    commitFlg = false
}, { deep: true })
</script>

<style scoped>
:deep(.el-form-item__error) {
    padding-top: 0;
}

:deep(.e-dropdown-menu, .el-dropdown-menu__item) {
    padding: 0 10px !important;
}

:deep(.pulse) {
    font-size: 28px !important;
}

:deep(.iconfont) {
    font-family: iconfont, serif !important;
}

:deep(.el-icon-point) {
    font-size: 13px !important;
}
</style>

<style>
.connectStyle.el-dialog .el-dialog__body {
    padding: 15px !important;
}

.connectStyle.el-dialog .el-dialog__header {
    border-bottom: 1px solid #e4e7ec;
}

.connectStyle.el-dialog .el-dialog__footer {
    padding: 10px 20px;
    border-top: 1px solid #e4e7ec;
}

.connectStyle.el-dialog .el-dialog__body .el-form-item {
    margin: 0
}

.connectStyle.el-dialog .el-dialog__body .el-form-item+.el-form-item {
    margin-top: 15px
}
</style>